package com.sun.designpatternsdemo.command

import android.os.Bundle
import android.widget.Button
import com.sun.designpatternsdemo.R
import com.sun.designpatternsdemo.app.AppConstant
import com.sun.designpatternsdemo.app.EMTagHandler
import com.sun.designpatternsdemo.base.BaseActivity
import com.sun.designpatternsdemo.databinding.ActivityCommandBinding
/**
 * 版权：xx公司 版权所有
 * @author sun
 * 版本：1.0
 * 创建日期：${DATE} ${TIME}
 * 描述：${DATA}
 * * 命令模式:
 * 定义：将"请求"封装成对象，以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
 * 简化: 将请求封装成对象，将动作请求者和动作执行者解耦。
 * 命令模式的核心就是把命令封装成类，对于命令执行者不需要知道现在执行的具体是什么命令。
 * <p>
 * 假设现在有电视、电脑、电灯等家电，现在需要你做个遥控器控制所有家电的开关，
 * 要求做到每个按钮对应的功能供用户个性化，对于新买入家电要有非常强的扩展性。
 */
class CommandActivity : BaseActivity<ActivityCommandBinding>() {
    private lateinit var controlPanel: ControlPanel
    private var views = arrayOf(
        R.id.bt_zero,
        R.id.bt_one,
        R.id.bt_two,
        R.id.bt_three,
        R.id.bt_four,
        R.id.bt_five,
        R.id.bt_six,
        R.id.bt_seven,
        R.id.bt_no
    )

    override fun layoutId(): Int = R.layout.activity_command

    override fun initView(savedInstanceState: Bundle?) {
        title = "命令模式"
        mDataBind.apply {
            tvDefine.text = EMTagHandler.fromHtml(AppConstant.COMMAND_DEFINE)
            setCommands()
            views.forEachIndexed { index, i ->
                findViewById<Button>(i).setOnClickListener {
                    controlPanel.keyPressed(index)
                }
            }
        }
    }

    private fun setCommands() {
        /**
         * 家电
         */
        val door = Door()
        val light = Light()
        val computer = Computer()
        val quickOpenCommand = QuickCommand(
            arrayOf(
                LightOnCommand(light), ComputerOnCommand(computer), DoorOpenCommand(door)
            )
        )
        val quickCloseCommand = QuickCommand(
            arrayOf(
                LightOffCommand(light), ComputerOffCommand(computer), DoorCloseCommand(door)
            )
        )
        /**
         * 一个控制器，假设是我们app界面
         */
        controlPanel = ControlPanel()
            .apply {
                setCommands(0, DoorOpenCommand(door))
                setCommands(3, DoorCloseCommand(door))
                setCommands(1, LightOnCommand(light))
                setCommands(4, LightOffCommand(light))
                setCommands(2, ComputerOnCommand(computer))
                setCommands(5, ComputerOffCommand(computer))
                //        controlPanel.keyPressed(8);//这个没有设置命令,但不会出问题,因为我们的NoCommand的功劳

                setCommands(6, quickOpenCommand)
                setCommands(7, quickCloseCommand)
            }
    }
}